package com.handu.luna.core.domain.promotion;


import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.PostLoad;
import javax.persistence.PrePersist;
import javax.persistence.Transient;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.format.annotation.DateTimeFormat;

import com.handu.luna.core.domain.goods.Brand;
import com.handu.luna.core.domain.goods.Goods;
import com.handu.luna.core.domain.search.PostForFreeActivitySearch;




@Entity
public class PostForFreeActivity extends Promotion{
	public static final String DELIMITER = ",";
    //private long brandId;  // 品牌ID
	//private long categoryId;  // 分类ID
	//private String goodSn;   //商品货号
	//private String keyword;   //关键字
	private String goodsIdArr;  //商品id字符串，以逗号分割
	@Transient
	private List<Goods> postForFreeSingleGoods;
	
	@NotNull(message="包邮名称不能为空")
	@Size(min=1,max=100, message="包邮名称长度超过限制！")
	private String postForFreeName; //包邮名称

	private PostForFreeType postForFreeType ;  //包邮类型
	public enum PostForFreeType {
		 
		SINGLEGOOD("单品限时包邮"), ORDER("全场限时包邮") ,BRAND("品牌限时包邮");
		public String description;
		PostForFreeType(final String description) {
			this.description = description;
		}

	}
	
	@Min(value = 1, message = "订单价格不能低于0")
	private BigDecimal orderPrice;// 订单价格
	
	


	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	private Date startDate;  //开始时间
	
	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	private Date endDate;   //结束时间	
    private String postForFreeInstruction;   //包邮说明

    //品牌名称
    private String brands; 
   
    @Transient private List<Long> brandsIdList;
	@Transient private List<Brand> brandsList;
	

	
	public String getStatus() {
        return initStatus(this.startDate,this.endDate);
    }

	public List<Brand> getBrandsList() {
		return brandsList;
	}

	public void setBrandsList(List<Brand> brandsList) {
		this.brandsList = brandsList;
	}

	@PostLoad
    public void init() {
        if(StringUtils.isNotBlank(brands)) {
        	brandsList = new ArrayList<>();
        	brandsIdList = new ArrayList<>();
            for (String brandStrId : this.strToList(brands)) {
                long brandId = Long.parseLong(brandStrId);
                brandsIdList.add(brandId);
                brandsList.add(context.getBrandRepository().findOne(brandId));
            }
        }
    }

    @PrePersist
    public void prePersist() {
        if(CollectionUtils.isNotEmpty(brandsIdList)) {
        	brands = this.listToStr(brandsIdList);
        }
    }

    public void update() {
        prePersist();
        context.getPostForFreeActivityRepository().save(this);
    }
    
    public String listToStr(List<Long> list) {
        StringBuilder sb = new StringBuilder();
        for (Long id : list) {
            sb.append(String.valueOf(id)).append(DELIMITER);
        }
        return sb.toString();
    }

    public List<String> strToList(String arrayString) {
        List<String> list = new ArrayList<String>();
        for(String item : arrayString.split(DELIMITER)) {
            list.add(item);
        }
        return list;
    }
    
    
	public String getPostForFreeName() {
		return postForFreeName;
	}

	public void setPostForFreeName(String postForFreeName) {
		this.postForFreeName = postForFreeName;
	}
	
	public PostForFreeType getPostForFreeType() {
		return postForFreeType;
	}

	public void setPostForFreeType(PostForFreeType postForFreeType) {
		this.postForFreeType = postForFreeType;
	}
	
	public BigDecimal getOrderPrice() {
		return orderPrice;
	}

	public void setOrderPrice(BigDecimal orderPrice) {
		this.orderPrice = orderPrice;
	}

	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public String getPostForFreeInstruction() {
		return postForFreeInstruction;
	}

	public void setPostForFreeInstruction(String postForFreeInstruction) {
		this.postForFreeInstruction = postForFreeInstruction;
	}

	public String getBrands() {
		return brands;
	}

	public void setBrands(String brands) {
		this.brands = brands;
	}

	public List<Long> getBrandsIdList() {
		return brandsIdList;
	}

	public void setBrandsIdList(List<Long> brandsIdList) {
		this.brandsIdList = brandsIdList;
	}

	public String getGoodsIdArr() {
		return goodsIdArr;
	}

	public void setGoodsIdArr(String goodsIdArr) {
		this.goodsIdArr = goodsIdArr;
	}
	

	public List<Goods> getPostForFreeSingleGoods() {
	        if (StringUtils.isNotBlank(goodsIdArr)){
	        	postForFreeSingleGoods = context.getGoodsRepository().findAll(Goods.in(goodsIdArr));
	        }
	        return postForFreeSingleGoods;
	    }

	public void setPostForFreeSingleGoods(List<Goods> postForFreeSingleGoods) {
		this.postForFreeSingleGoods = postForFreeSingleGoods;
    }
	 
    

	public PostForFreeActivity(){  //构造函数
		super();
	}
	
	 public PostForFreeActivity(String postForFreeName,PostForFreeType postForFreeType,Date startDate, Date endDate,String postForFreeInstruction){
	    	super();
	    	this.postForFreeName = postForFreeName;
	    	this.postForFreeType = postForFreeType;
	    	this.startDate = startDate;
	    	this.endDate = endDate;
	    	this.postForFreeInstruction = postForFreeInstruction;	  		
		}
	 
	 
	 
	 public Page<PostForFreeActivity> findAll(PostForFreeActivitySearch postForFreeActivitySearch,Pageable pageable){
			Page<PostForFreeActivity> postForFreeActivity = context.getPostForFreeActivityRepository().findAll(PostForFreeActivity.selectCondition(postForFreeActivitySearch), pageable);
		
			return postForFreeActivity;
	 }
	 

	 public static Specification<PostForFreeActivity> selectCondition(PostForFreeActivitySearch postForFreeActivitySearch) {
			return new Specification<PostForFreeActivity>() {
				@Override
				public Predicate toPredicate(Root<PostForFreeActivity> root,
						CriteriaQuery<?> query, CriteriaBuilder builder) {
					Predicate predicate = builder.conjunction();
					List<Expression<Boolean>> expressions = predicate.getExpressions();								
					if (StringUtils.isNotBlank(postForFreeActivitySearch.getPostForFreeName())) {  //包邮名称				
						expressions.add(builder.like(root.<String> get("postForFreeName"), "%"+postForFreeActivitySearch.getPostForFreeName() + "%")); // 包邮名称
					}
					//时间
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					Date date1 = null;
					Date date2 = null;
					Date nowdate = null;
					Date now = new Date();
					String nowtime = sdf.format( now );

					if(StringUtils.isNotBlank(postForFreeActivitySearch.getStartTime())){
						try {
							date1 = sdf.parse(postForFreeActivitySearch.getStartTime());
						} catch (ParseException e) {
							e.printStackTrace();
						}
						expressions.add(builder.greaterThanOrEqualTo(root.<Date>get("startDate"), date1));
					}

					if(StringUtils.isNotBlank(postForFreeActivitySearch.getEndTime())){
						try {
							date2 = sdf.parse(postForFreeActivitySearch.getEndTime());
						} catch (ParseException e) {
							e.printStackTrace();
						}
						expressions.add(builder.lessThanOrEqualTo(root.<Date>get("startDate"), date2));
					}
					
					
				/*	if(StringUtils.isNotBlank(postForFreeActivitySearch.getStartTime()) && StringUtils.isNotBlank(postForFreeActivitySearch.getEndTime())){
						
						try {
							date1 = sdf.parse(postForFreeActivitySearch.getStartTime());
							date2 = sdf.parse(postForFreeActivitySearch.getEndTime());
						} catch (ParseException e) {
							e.printStackTrace();
						}
						//ZonedDateTime zoned_start =	date1.toInstant().atZone(ZoneId.of("UTC+08:00"));
						//ZonedDateTime zoned_end =	date2.toInstant().atZone(ZoneId.of("UTC+08:00"));
						//expressions.add(builder.between(root.<ZonedDateTime>get("startDate"), zoned_start, zoned_end)); // 创建时间createdTime
						expressions.add(builder.between(root.<Date>get("startDate"), date1, date2));
					}*/
					
					if(postForFreeActivitySearch.getPostForFreeType()!=null){
						expressions.add(builder.equal(root.<PostForFreeType>get("postForFreeType"), postForFreeActivitySearch.getPostForFreeType()));
					}
					if(StringUtils.isNotBlank(postForFreeActivitySearch.getBrandId())){
						expressions.add(builder.or(builder.like(root.get("brands"), postForFreeActivitySearch.getBrandId()+",%"),
												   builder.like(root.get("brands"), "%,"+postForFreeActivitySearch.getBrandId()+",%"),
												   builder.like(root.get("brands"), "%,"+postForFreeActivitySearch.getBrandId()),
												   builder.equal(root.get("brands"), postForFreeActivitySearch.getBrandId())));
					}
					
					if(postForFreeActivitySearch.getActivitiesState()!=0){
						try {
							nowdate = sdf.parse(nowtime);
						} catch (ParseException e) {
							e.printStackTrace();
						}
						if(postForFreeActivitySearch.getActivitiesState()==1){
							
							expressions.add(builder.lessThanOrEqualTo(root.get("startDate"), nowdate)); 
							expressions.add(builder.greaterThanOrEqualTo(root.get("endDate"), nowdate));
							
						}else if(postForFreeActivitySearch.getActivitiesState()==2){
							
							expressions.add(builder.greaterThanOrEqualTo(root.get("startDate"), nowdate));
							
						}else if(postForFreeActivitySearch.getActivitiesState()==3){
							
							expressions.add(builder.lessThanOrEqualTo(root.get("endDate"), nowdate)); 
						}
					}
					
					return query.where(predicate).getRestriction();

				}
			};
		}
	 @SuppressWarnings({ "rawtypes", "unchecked" })
	public void merge(String[] fields) {
			List<Long> userRankIdList = this.brandsIdList;
			if(!this.isNew()){
				Object thisDomainInDB = null;
				try {
	                thisDomainInDB = BeanUtils.cloneBean(((JpaRepository) getRepository()).findOne(this.getId()));
				} catch (IllegalAccessException | InstantiationException
						| InvocationTargetException | NoSuchMethodException e1) {
					logger.debug("error in copy merge a domain",e1);
				}			
				for(String field : fields){
					try {
	                    String property = BeanUtils.getProperty(this,field);
	                    if(field.endsWith("Date") || field.endsWith("startDate") ||  field.endsWith("endDate")) {
	                        Date date = new SimpleDateFormat("EE MMM dd HH:mm:ss 'CST' yyyy", java.util.Locale.US).parse(property);
	                        BeanUtils.copyProperty(thisDomainInDB, field, date);
	                    }else {
	                        BeanUtils.copyProperty(thisDomainInDB, field, property);
	                    }
					} catch (IllegalAccessException | InvocationTargetException
							| NoSuchMethodException e) {
						logger.debug("error in copy merge a domain",e);
					} catch (ParseException e) {
	                    e.printStackTrace();
	                }
	            }
				try {
					BeanUtils.copyProperties(this, thisDomainInDB);
				} catch (IllegalAccessException | InvocationTargetException e) {
					logger.debug("error in copy merge a domain",e);
				}
			}
			this.setBrandsIdList(userRankIdList);
		}
	 
	 /**
	  * 查询所有处于包邮的商品Id 如果返回的set第一个数是0 表示所有的商品现在都是包邮的
	  * @param brand
	  * @return
	  */
	public Set<Long> searchPost4Freeing(String brand ,final Set<Long> qualifiedGoodsIds){
		 Set<Long> goodsIds = new LinkedHashSet<Long>();
		 /*** 不再考虑全场限时包邮活动  **/
//		 //若有正在进行的全场限时包邮活动  那么直接返回0 表示所有的商品都是包邮的
//		 if(CollectionUtils.isNotEmpty(context.getPostForFreeActivityRepository().findAll(selectCondition(new PostForFreeActivitySearch(1, PostForFreeType.ORDER))))){
//			 qualifiedGoodsIds.add((long) 0);
//			 return qualifiedGoodsIds;
//		 }
		 /**
		  * 若无正在进行的全场限时包邮活动 那么查询指定品牌或者所有品牌  
		  * 若查询指定品牌的包邮 那么就不必查找单品包邮的
		  */
		 List<PostForFreeActivity> activitiesOfBrands;
		 if(StringUtils.isNotBlank(brand)){
			 activitiesOfBrands = context.getPostForFreeActivityRepository().findAll(selectCondition(new PostForFreeActivitySearch(1, PostForFreeType.BRAND,brand)));
		 }else{
			 activitiesOfBrands = context.getPostForFreeActivityRepository().findAll(selectCondition(new PostForFreeActivitySearch(1, PostForFreeType.BRAND))); 
		 }
		 if(CollectionUtils.isNotEmpty(activitiesOfBrands)){
			 if(StringUtils.isNotBlank(brand)){
				 List<Goods> goods = context.getGoodsRepository().findbyBrand4Portal(Long.parseLong(brand));
				 if(CollectionUtils.isNotEmpty(goods)){
					 for (Goods goods2 : goods) {
						goodsIds.add(goods2.getId());
					}
				 }
			 }else{
				 Set<Long> brands = new HashSet<Long>();
				 for (PostForFreeActivity postForFreeActivity : activitiesOfBrands) {
					for(String s : postForFreeActivity.getBrands().split(",")){
						if(StringUtils.isNotBlank(s)){
							brands.add(Long.parseLong(s));
						}
					}
				 }
				List<Goods> goods_In_brands = context.getGoodsRepository().findAll(new Specification<Goods>() {
					public Predicate toPredicate(Root<Goods> root,
							CriteriaQuery<?> query, CriteriaBuilder cb) {
						return query.where(cb.and(cb.equal(root.<Boolean> get("deleted"),false),
									              cb.equal(root.<Boolean> get("displayed"),true),
									              root.get("brandId").in(brands))).getRestriction();
					}
				}); 
				if(CollectionUtils.isNotEmpty(goods_In_brands)){
					for(Goods g : goods_In_brands){
						goodsIds.add(g.getId());
					}
				}
			 }
				 
		 }
		 List<String> activitiesOfSingle = context.getPostForFreeActivityRepository().findCurrentPost4FreeGoodsId(PostForFreeType.SINGLEGOOD);
		 //如果指定了品牌 从单品优惠里面过滤下品牌
		 if(CollectionUtils.isNotEmpty(activitiesOfSingle)){
			 Set<Long> goodsIdOfSingleActivity = new HashSet<Long>();
			 
			 for(String ids:activitiesOfSingle){
				 if(StringUtils.isNotBlank(ids)){
					 for(String gid : ids.split(",")){
						 goodsIdOfSingleActivity.add(Long.parseLong(gid));
					 } 
				 }
			 }
			 //过滤
			 if(CollectionUtils.isNotEmpty(goodsIdOfSingleActivity)){
				 if(StringUtils.isNotBlank(brand)){
					goodsIdOfSingleActivity = context.getGoodsRepository().filterGoodsIdByBrand(Long.parseLong(brand), goodsIdOfSingleActivity); 
				 }
			 }
			 
			 goodsIds.addAll(goodsIdOfSingleActivity);
		 }
		 
		 //整合根据包邮查询出的商品ID和前面的条件查询出来的商品ID 
		 if(CollectionUtils.isNotEmpty(goodsIds) && CollectionUtils.isNotEmpty(qualifiedGoodsIds)){
			 List<Goods> temp = context.getGoodsRepository().findAll(new Specification<Goods>() {
				 
				 @Override
				 public Predicate toPredicate(Root<Goods> root,
						 CriteriaQuery<?> query, CriteriaBuilder cb) {
					 
					 return query.where(cb.and(root.get("id").in(goodsIds),root.get("id").in(qualifiedGoodsIds))).getRestriction();
				 }
			 });
			 if(CollectionUtils.isNotEmpty(temp)){
				 qualifiedGoodsIds.clear();
				 for(Goods g : temp){
					 qualifiedGoodsIds.add(g.getId());
				 }
			 }
			 return qualifiedGoodsIds;
			 
		 }
		 
		 return CollectionUtils.isNotEmpty(goodsIds)?goodsIds:(CollectionUtils.isNotEmpty(qualifiedGoodsIds)?qualifiedGoodsIds:new LinkedHashSet<Long>());
	 }
	 

	
}
